<template>
  <div class="image-list clearfix" :class="{ multiple }">
    <!-- 文件列表 -->
    <!-- draggable是拖拽组件 -->
    <draggable
      v-if="selectedItems.length"
      v-model="selectedItems"
      item-key="fileId"
      @start="drag = true"
      @end="drag = false"
      @update="onChange"
    >
      <template #item="{ element, index }">
        <div
          class="file-item"
          :style="{
            width: `${width}px`,
            height: `${height}px`,
            lineHeight: `${height}px`
          }"
        >
          <a-image
            v-if="element.url != null && element.url !== ''"
            :src="element.url"
            :placeholder="true"
            :fallback="defaultUrl"
            :width="width - 6"
            :height="height - 6"
          />
          <a-image v-else :placeholder="true" :src="defaultUrl" :preview="false" />
          <CloseCircleOutlined class="icon-close" @click="handleDeleteFileItem(index)" />
        </div>
      </template>
    </draggable>
    <!-- 图片选择器 -->
    <!-- 如果单选, selectedItems无内容时 显示 -->
    <!-- 如果多选, selectedItems数量小于 maxNum 显示 -->
    <div
      v-show="(!multiple && selectedItems.length <= 0) || (multiple && selectedItems.length < maxNum)"
      class="selector"
      :style="{ width: `${width}px`, height: `${height}px` }"
      title="点击选择图片"
      @click="handleSelectImage"
    >
      <PlusOutlined :style="{ fontSize: `${width * 0.4}px` }" />
    </div>
    <!-- 文件选择器 -->
    <file-modal
      ref="fileModalRef"
      :multiple="multiple"
      :max-num="maxNum"
      :selected-num="selectedItems.length"
      @on-file-selected="handleSelectImageSubmit"
    />
  </div>
</template>

<script name="SelectImage" lang="ts" setup>
import { cloneDeep } from "lodash-es";
import draggable from "vuedraggable";

const emit = defineEmits(["update:value"]);
const props = defineProps({
  value: {
    type: [Number, Array],
    default: 0
  },
  // 多选模式, 如果false为单选
  multiple: {
    type: Boolean,
    default: false
  },
  // 最大选择的数量限制, multiple模式下有效
  maxNum: {
    type: Number,
    default: 100
  },
  // 已选择的数量
  defaultList: {
    type: Array,
    default: () => []
  },
  // 元素的尺寸(宽)
  width: {
    type: Number,
    default: 80
  },
  // 元素的尺寸(高)
  height: {
    type: Number,
    default: 80
  }
});

const defaultUrl = new URL("./../../assets/images/default.png", import.meta.url).href;

const selectedItems = ref<Array<any>>([]);
const allowProps = ref<boolean>(true);

const onChange = () => {
  if (selectedItems.value.length <= 0) {
    emit("update:value", props.multiple ? [] : 0);
    return;
  }
  const fileId = props.multiple ? selectedItems.value.map((item: any) => item.fileId) : selectedItems.value[0].fileId;
  emit("update:value", fileId, selectedItems);
};

// 打开文件选择器
const fileModalRef = ref();
const handleSelectImage = () => {
  fileModalRef.value.show();
};

// 文件库modal确认回调
const handleSelectImageSubmit = (result: any) => {
  if (result.length > 0) {
    // 记录选中的图片列表
    selectedItems.value = props.multiple ? selectedItems.value.concat(result) : result;
    onChange();
  }
};

// 删除文件
const handleDeleteFileItem = (index: number) => {
  selectedItems.value.splice(index, 1);
  if (selectedItems.value.length === 0) {
    allowProps.value = false;
  }
  onChange();
};

watch(props, () => {
  if (props.defaultList.length && !selectedItems.value.length && allowProps.value) {
    selectedItems.value = cloneDeep(props.defaultList);
    onChange();
  }
});
</script>

<style lang="less" scoped>
.image-list {
  margin-bottom: -10px;
  // 多选模式下margin
  &.multiple {
    .file-item,
    .selector {
      margin-right: 10px;
      margin-bottom: 10px;
    }
  }
}

// 文件元素
.file-item {
  position: relative;
  float: left;
  padding: 2px;
  border: 1px solid #ddd;
  background: #fff;
  :deep(.ant-image) {
    //display: flex;
    align-items: center;

    img {
      display: block;
      max-width: 100%;
      max-height: 100%;
      background: no-repeat center center / 100%;
      align-items: center;
    }
  }
  &:hover {
    .icon-close {
      display: block;
    }
  }
  .icon-close {
    display: none;
    position: absolute;
    top: -8px;
    right: -8px;
    cursor: pointer;
    font-size: 16px;
    color: #c5c5c5;
    &:hover {
      color: #7d7d7d;
    }
  }
  &:hover {
    border: 1px solid #a7c3de;
  }
}

// 选择器
.selector {
  float: left;
  border: 1px dashed #e2e2e2;
  text-align: center;
  color: #dad9d9;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  &:hover {
    border: 1px dashed @theme-color;
    color: @theme-color;
  }
}
</style>
